package com.atguigu.tingshu.account.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.MqOpsService;
import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@Service
public class MqOpsServiceImpl implements MqOpsService {
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserAccountService userAccountService;
    @Override
    public void userAccountInit(String userId) {
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(Long.parseLong(userId));
        userAccountMapper.insert(userAccount);
    }

    @Override
    public void minus(String orderNo) {
        //获取锁定信息
        String userAccountResultKey = "user:account:data" + orderNo;
        //设置分布式锁,防止定时任务重试发送消息重复修改
        String msgRepeatLockKey = "msg:repeat:" + orderNo;
        String accountLockResultVoToString = redisTemplate.opsForValue().get(userAccountResultKey);
        if (!StringUtils.hasText(accountLockResultVoToString)){
            return;
        }
        AccountLockResultVo accountLockResultVo = JSONObject.parseObject(accountLockResultVoToString, AccountLockResultVo.class);
        BigDecimal amount = accountLockResultVo.getAmount();
        Long userId = accountLockResultVo.getUserId();
        String content = accountLockResultVo.getContent();
        //进行消费扣减账户余额
        try {
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(msgRepeatLockKey, orderNo,2, TimeUnit.DAYS);
            if (aBoolean){
                //扣减余额
                userAccountMapper.minus(userId,amount);
                //记录流水
                userAccountService.logs(userId, "消费" + content, "1204", amount, orderNo);
                //扣减后删除锁定信息
                redisTemplate.delete(userAccountResultKey);
            }
        } catch (Exception e) {
            //有异常删除锁进行重试
            redisTemplate.delete(msgRepeatLockKey);
            throw new GuiguException(201, "业务执行失败");
        }

    }

    @Override
    public void unLock(String orderNo) {
        //获取锁定信息
        String userAccountResultKey = "user:account:data" + orderNo;
        //设置分布式锁,防止定时任务重试发送消息重复修改
        String msgRepeatLockKey = "msg:repeat:" + orderNo;
        String accountLockResultVoToString = redisTemplate.opsForValue().get(userAccountResultKey);
        if (!StringUtils.hasText(accountLockResultVoToString)){
            return;
        }
        AccountLockResultVo accountLockResultVo = JSONObject.parseObject(accountLockResultVoToString, AccountLockResultVo.class);
        BigDecimal amount = accountLockResultVo.getAmount();
        Long userId = accountLockResultVo.getUserId();
        String content = accountLockResultVo.getContent();
        //进行解锁账户余额
        try {
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(msgRepeatLockKey, orderNo,2, TimeUnit.DAYS);
            if (aBoolean){
                //解锁余额
                userAccountMapper.unLock(userId,amount);
                //记录流水
                userAccountService.logs(userId, "解锁" + content, "1203", amount, orderNo);
                //解锁后删除锁定信息
                redisTemplate.delete(userAccountResultKey);
            }
        } catch (Exception e) {
            //有异常删除锁进行重试
            redisTemplate.delete(msgRepeatLockKey);
            throw new GuiguException(201, "业务执行失败");
        }
    }
}
